package com.ecoolex.hotel.saas.platform.graphql;

import java.util.List;
import java.util.stream.Collectors;

import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.NonNull;

import com.alibaba.fastjson.JSON;
import com.ecoolex.framework.common.enums.ResultCode;
import com.ecoolex.framework.common.pojo.Page;
import com.ecoolex.framework.common.pojo.Pagination;
import com.ecoolex.framework.common.util.Assert;
import com.ecoolex.framework.common.util.Check;
import com.ecoolex.framework.modularize.api.auth.annotation.PlatformAuthoritativeRegister;
import com.ecoolex.framework.modularize.api.auth.platform.PlatformMemberAuthority;
import com.ecoolex.framework.modularize.api.service.storage.StorageInfo;
import com.ecoolex.framework.modularize.api.service.storage.StorageService;
import com.ecoolex.framework.web.api.graphql2.annotation.GraphQL2Module;
import com.ecoolex.framework.web.api.graphql2.annotation.MutationField;
import com.ecoolex.framework.web.api.graphql2.annotation.QueryField;
import com.ecoolex.framework.web.api.graphql2.annotation.Source;
import com.ecoolex.framework.web.api.graphql2.annotation.TypeField;
import com.ecoolex.framework.web.api.graphql2.annotation.GraphQL2Module.Type;
import com.ecoolex.hotel.saas.entity.PresaleCouponOrder;
import com.ecoolex.hotel.saas.entity.PresaleCouponOrderAfterSales;
import com.ecoolex.hotel.saas.entity.PresaleCouponOrderAfterSalesRecord;
import com.ecoolex.hotel.saas.enums.PresaleCouponOrderAfterSalesStatus;
import com.ecoolex.hotel.saas.platform.core.PlatformConstant;
import com.ecoolex.hotel.saas.pojo.QueryPresaleCouponOrderAfterSalesDTO;
import com.ecoolex.hotel.saas.ws.PresaleCouponOrderService;
import com.google.common.collect.Lists;

@GraphQL2Module(type = Type.Platform, description = "预售券售后单")
@PlatformAuthoritativeRegister(parentKey = PlatformConstant.AUTH_PROJECT_KEY,
	key = PresaleCouponOrderAfterSalesGraphql.AUTH,
	name = "预售券售后单管理",
	remark = "预售券售后单管理")
public class PresaleCouponOrderAfterSalesGraphql {

	public static final String AUTH = PlatformConstant.AUTH_PROJECT_KEY + "-PRESALE-COUPON-ORDER-AFTER-SALES";
	
	private static final String AUTH_GET = AUTH + "-GET";
	
	private static final String AUTH_QUERY = AUTH + "-QUERY";
	
	private static final String AUTH_AGREE = AUTH + "-AGREE";
	
	private static final String AUTH_REFUSE = AUTH + "-REFUSE";
	
	@Reference
	private PresaleCouponOrderService presaleCouponOrderService;
	
	@Autowired
	private StorageService storageService;
	
	@TypeField(type = PresaleCouponOrderAfterSales.class, field = "canDealWith", description = "能处理售后单")
	public Boolean canDealWith(@Source PresaleCouponOrderAfterSales source) {
		return PresaleCouponOrderAfterSalesStatus.canDealWith(source.getStatus());
	}
	
	@TypeField(type = PresaleCouponOrderAfterSales.class, field = "presaleCouponOrder", description = "预售券订单")
	public PresaleCouponOrder presaleCouponOrder(@Source PresaleCouponOrderAfterSales source) {
		return presaleCouponOrderService.get(source.getOrderId());
	}
	
	@TypeField(type = PresaleCouponOrderAfterSales.class, field = "presaleCouponOrderAfterSalesRecordList", description = "预售券售后记录")
	public List<PresaleCouponOrderAfterSalesRecord> afterSalesRecord(@Source PresaleCouponOrderAfterSales source){
		return presaleCouponOrderService.afterSalesRecord(source.getAfterSalesId());
	}
	
	@TypeField(type = PresaleCouponOrderAfterSalesRecord.class, field = "recordEvidenceImage", description = { "售后记录凭证图片" })
	public List<StorageInfo> recordEvidenceImage(@Source PresaleCouponOrderAfterSalesRecord source) {
		if(Check.notNullOrEmpty(source.getEvidenceImage())) {
			return JSON.parseArray(source.getEvidenceImage(), String.class).stream()
				.map(storageService::get)
				.filter(Check::notNull)
				.collect(Collectors.toList());
		}
		return Lists.newArrayList();
	}
	
	@TypeField(type = PresaleCouponOrderAfterSales.class, field = "evidenceImage", description = { "凭证图片" })
	public List<StorageInfo> evidenceImage(@Source PresaleCouponOrderAfterSales source) {
		if(Check.notNullOrEmpty(source.getEvidenceImage())) {
			return JSON.parseArray(source.getEvidenceImage(), String.class).stream()
				.map(storageService::get)
				.filter(Check::notNull)
				.collect(Collectors.toList());
		}
		return Lists.newArrayList();
	}
	
	@QueryField(field = "presaleCouponOrderAfterSales", description = { "预售券售后单详情" })
	@PlatformAuthoritativeRegister(parentKey = AUTH, key = AUTH_GET, name = "预售券售后单详情")
	public PresaleCouponOrderAfterSales get(@NonNull Integer afterSalesId, PlatformMemberAuthority user) {
		user.assertAuth(AUTH_GET);
		return presaleCouponOrderService.getAfterSales(afterSalesId);
	}
	
	@QueryField(field = "presaleCouponOrderAfterSalesList", description = { "预售券售后单列表" })
	@PlatformAuthoritativeRegister(parentKey = AUTH, key = AUTH_QUERY, name = "预售券售后单列表")
	public Pagination<PresaleCouponOrderAfterSales> query(@NonNull QueryPresaleCouponOrderAfterSalesDTO query, @NonNull Page page, PlatformMemberAuthority user){
		user.assertAuth(AUTH_QUERY);
		return presaleCouponOrderService.queryAfterSales(query, page);
	}
	
	@MutationField(field = "agreePresaleCouponOrderRefund", description = "同意退款申请")
	@PlatformAuthoritativeRegister(parentKey = AUTH, key = AUTH_AGREE, name = "同意退款申请")
	public PresaleCouponOrderAfterSales agreeRefund(@NonNull Integer afterSalesId, PlatformMemberAuthority user) {
		user.assertAuth(AUTH_AGREE);
		PresaleCouponOrderAfterSales afterSales = presaleCouponOrderService.getAfterSales(afterSalesId);
		Assert.isTrue(Check.notNull(afterSales),ResultCode.VERIFY.build(1), "售后单不存在");
		return presaleCouponOrderService.agreeRefund(afterSales, user.userName());
	}
	
	@MutationField(field = "refusePresaleCouponOrderRefund", description = "拒绝退款申请")
	@PlatformAuthoritativeRegister(parentKey = AUTH, key = AUTH_REFUSE, name = "拒绝退款申请")
	public PresaleCouponOrderAfterSales refuseRefund(@NonNull Integer afterSalesId, String auditOpinion, PlatformMemberAuthority user) {
		user.assertAuth(AUTH_REFUSE);
		PresaleCouponOrderAfterSales afterSales = presaleCouponOrderService.getAfterSales(afterSalesId);
		Assert.isTrue(Check.notNull(afterSales),ResultCode.VERIFY.build(1), "售后单不存在");
		afterSales.setAuditOpinion(auditOpinion);
		return presaleCouponOrderService.refuseRefund(afterSales, user.userName());
	}
}
